<?php
/**
 * FastApp.
 * 3/1/25
 * @Author deepsea
 * @Contact (telegram:deepsea159)
 */

namespace App\Hoenix\Api\Service;

use App\Fastapp\Api\Service\Telegram;
use App\Hoenix\Model\HoenixConcubine;
use App\Hoenix\Model\HoenixConcubineOrder;
use App\Hoenix\Model\HoenixKeyword;
use Carbon\Carbon;
use Telegram\Bot\Api;

class TgCustomerBotService
{
    public static ?Api $cBot = null;

    public static function skipBotMessage(): bool
    {
        return true;
    }

    public static function handle(array $data, Api $bot, int $bot_id): void
    {
        if (isset($data['left_chat_member']) || $data['chat']['type'] != 'private') return;
        if (isset($data['entities'])) {
            list($cmds) = Telegram::parseEntity($data['entities'], $data['text']);
            if ($cmds[0]) self::cmd($cmds[0], $data['chat']['id'], $bot);
        } else {
            self::send($data['text'], 1, $data['chat']['id'], $bot);
        }
    }

    public static function send(string $kw, int $page, int $chat_id, Api $bot): void
    {
        if (mb_strlen($kw) == 1 && (is_numeric($kw) || ctype_alpha($kw) || preg_match('/[\x{3000}-\x{303F}\x{FF00}-\x{FFEF}\x{0020}-\x{002F}\x{003A}-\x{0040}\x{005B}-\x{0060}\x{007B}-\x{007E}]/u', $kw)))
            $kw = '';
        $words = [];
        if ($kw) {
            $keywds = 'h:c:' . md5($kw);
            $words = cache()->get($keywds);
            if (!$words) {
                $cmd = 'python3 ' . dirname(BASE_PATH) . '/py/cut.py ';
                exec($cmd . $kw, $output);
                $words = json_decode($output[0],true);
                cache()->set($keywds, $words, 86400);
            }
        }
        $md = null;
        if ($words) {
            $ids = HoenixKeyword::query()
                ->join('hoenix_concubine_keyword as ck', 'ck.kid', '=', 'hoenix_keyword.id')
                ->join('hoenix_concubine as c', 'c.id', '=', 'ck.concubine_id')
                ->whereIn('kw', $words)
                ->orderByDesc('c.sort')
                ->limit(2)->offset($page - 1)->pluck('c.id')->toArray();
            if ($ids) {
                $md = HoenixConcubine::query()->find($ids[0]);
                if (count($ids) == 1) $md->is_end = true; else $md->is_end = false;
            }
        }
        if (!$md) {
            $res = HoenixConcubine::query()
                ->orderByDesc('sort')->orderByDesc('id')
                ->limit(2)->offset($page - 1)->get();
            if (!$res->count()) return;
            $md = $res->first();
            if ($res->count() == 1) $md->is_end = true; else $md->is_end = false;
        }
        list($message, $media) = TgConcubineBotService::formatInfo($md, 1);
        $res = [
            'chat_id' => $chat_id,
            'media' => json_encode($media, JSON_UNESCAPED_UNICODE),
        ];
        $bot->sendMediaGroup($res);

        $kb = [
            ['text' => '上一位', 'callback_data' => 'next_' . ($page - 1) . '_' . $kw],
            ['text' => '下一位', 'callback_data' => 'next_' . ($page + 1) . '_' . $kw]
        ];
        if ($page == 1) array_shift($kb);
        if ($md->is_end) array_pop($kb);
        $res = [
            'chat_id' => $chat_id,
            'parse_mode' => 'HTML',
            'text' => $message,
            'reply_markup' => json_encode([
                'inline_keyboard' => [
                    $kb,
                    [
                        ['text' => '预约', 'callback_data' => 'order_' . $md->id]
                    ]
                ]
            ], JSON_UNESCAPED_UNICODE)
        ];
        $bot->sendMessage($res);
    }

    public static function cmd(string $cmd, int $chat_id, Api $bot): void
    {
        $message = '';
        $reply_markup = [];
        if ($cmd == '/start') {
            $msg[] = '===欢迎使用===';
            $msg[] = '输入关键词筛选服务费人员';
            $message = implode("\n", $msg);
        }
        if ($cmd == '/my') {
            $reply_markup = [
                'inline_keyboard' => [
                    [
                        ['text' => '', 'callback_data' => ''],
                    ]
                ]
            ];
        }
        $send = [
            'chat_id' => $chat_id,
            'parse_mode' => 'HTML',
            'text' => $message,
        ];
        $bot->sendMessage($send);
    }

    public static function callbackQuery(array $data, Api $bot, int $bot_id): void
    {
        $res = redis()->hMGet('bot:' . $bot_id, ['account_type', 'robot_id']);
        $uid = Telegram::getUid((string)$data['from']['id'], $res['account_type']);
        if (!$uid) $uid = Telegram::createUser(array_merge($data['from'], ['type' => $res['account_type']]));
        if (!user_lock($uid)) return;
        try {
            @list($cmd, $param, $param2) = explode('_', $data['data']);
            if ($cmd == 'next') self::send($param2, (int)$param, $data['message']['chat']['id'], $bot);
            elseif ($cmd == 'order') {
                $msg[] = $data['message']['text'];
                $map = [
                    'user_id' => $uid,
                    'concubine_id' => $param,
                    'accept' => 0
                ];
                $order = HoenixConcubineOrder::query()->where($map)->orderByDesc('id')->first();
                $t = Carbon::now();
                if (!$order || $order->updated_at->diffInMinutes($t) > 15) {
                    if ($order) {
                        $order_msg[] = '===你有新的订单,已超时未处理===';
                        $msg[] = '<u>===以为你吹单===</u>';
                        $msg[] = "\n <u>时间: " . $t->toDateTimeString() . "</u>";
                        $map['updated_at'] = date('Y-m-d H:i:s');
                    } else {
                        $msg[] = "\n \n <u>===以为你预约，请等待服务接单===</u>";
                        $msg[] = "\n <u>时间: " . $t->toDateTimeString() . "</u>";
                        $map['created_at'] = $map['updated_at'] = $t->toDateTimeString();
                        $order_msg[] = '===你有新的订单===';
                        $map['concubine_user_id'] = HoenixConcubine::query()->where(['id' => $param])->value('user_id') ?: 0;
                        $order = new HoenixConcubineOrder();
                    }
                    $order->fill($map);
                    $order->save();
                    $order_msg[] = '';
                    $order_msg[] = '时间：' . $order->created_at->toDateTimeString();
                    $order_msg[] = '预约用户id：<code>' . $data['from']['id'] . '</code>';
                    $order_msg[] = '💡是否推送联系方式👇';
                    self::getCBot($res['robot_id'])->sendMessage([
                        'chat_id' => (int)get_user_cache('tgid', $order->concubine_user_id),
                        'parse_mode' => 'HTML',
                        'text' => implode("\n", $order_msg),
                        'reply_markup' => json_encode([
                            'inline_keyboard' => [
                                [
                                    ['text' => '拒绝', 'callback_data' => 'order_n_' . $order->id],
                                    ['text' => '接单', 'callback_data' => 'order_y_' . $order->id],
                                ]
                            ]
                        ], JSON_UNESCAPED_UNICODE)
                    ]);
                }
                if (!str_contains($data['message']['text'], '===')) $bot->editMessageText([
                    'chat_id' => $data['message']['chat']['id'],
                    'message_id' => $data['message']['message_id'],
                    'reply_markup' => json_encode($data['message']['reply_markup'], JSON_UNESCAPED_UNICODE),
                    'parse_mode' => 'HTML',
                    'text' => implode("\n", $msg),
                ]);
            }
            user_unlock($uid);
        } catch (\Throwable $throwable) {
            user_unlock($uid);
            sys_notify($throwable->getMessage() . $throwable->getTraceAsString());
        }
    }

    public static function getCBot(int|string $bot_id): Api
    {
        if (self::$cBot) return self::$cBot;
        self::$cBot = new Api(redis()->hGet('bot:' . $bot_id, 'token'));;
        return self::$cBot;
    }

    public static function init(Api $bot): void
    {
        $bot->deleteMyCommands();
        $commands = [
            ['command' => 'start', 'description' => '首页'],
            ['command' => 'my', 'description' => '我的'],
        ];
        $bot->setMyCommands(['commands' => $commands]);
    }
}